//VMwareCandidates
//
//Copyright (C) 8/13/2007 Joseph Lee Callen
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.DirectoryServices;
using System.Threading;
//using SoftwareFX.ChartFX.Lite;


namespace VMwareCandidates
{
    public partial class FormVMCandidates : Form
    {
        private Thread tRetrieveActiveDirectories;
        private Thread tRetrieveServers;
        private Thread tUpdateProgressBar;
        private System.DirectoryServices.DirectorySearcher serverSearcher;
        private ServerMonitoring sm;

        
        public FormVMCandidates()
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            
            InitializeComponent();

            dateTimePickerEndDate.Value = System.DateTime.Now.AddHours(73);
            tRetrieveActiveDirectories = new Thread(ListActiveDirectories);
            tRetrieveActiveDirectories.Start();
            
            //chartMetrics.SerLeg[0] = "CPU%";
            //chartMetrics.SerLeg[1] = "Disk I/O";

            tUpdateProgressBar = new Thread(new ThreadStart(ThreadUpdateProgressBar));
            tUpdateProgressBar.Start();  
            
        }

        private void ListActiveDirectories()
        {
            string rDSE = "";
            try
            {
                System.DirectoryServices.DirectorySearcher dseSearch
                    = new System.DirectoryServices.DirectorySearcher();
                rDSE = dseSearch.SearchRoot.Path;

                /* ** Here is the cross-threading issue ** */
                this.comboBoxDomain.Items.Add(rDSE);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
            }

            using (DirectoryEntry rAD = new DirectoryEntry(rDSE))
            {
                try
                {
                    serverSearcher = new System.DirectoryServices.DirectorySearcher(rAD);
                    serverSearcher.PageSize = 10000;
                    serverSearcher.Filter = "(ObjectClass=computer)";
                    serverSearcher.SizeLimit = 10000;
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine(e.Message);
                }
            }
        }

        private void ActiveDirectoryComputers()
        {
            toolStripStatusLabel.Text = "Enumerating the Active Directory...";
            System.Collections.ArrayList alServers = new System.Collections.ArrayList();
            try
            {
                foreach (System.DirectoryServices.SearchResult srEntry in serverSearcher.FindAll())
                {
                    string[] name = srEntry.GetDirectoryEntry().Name.ToString().Split('=');
                    alServers.Add(name[1]);
                }
                alServers.Sort();
                listBoxServers.Items.AddRange(alServers.ToArray());
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
            }
            toolStripStatusLabel.Text = listBoxServers.Items.Count + " PCs Available";
        }
        private void comboBoxDomain_SelectionChangedCommitted(object sender, EventArgs e)
        {
            listBoxServers.Items.Clear();
            listBoxServers.Refresh();

            tRetrieveServers = new Thread(new ThreadStart(ActiveDirectoryComputers));
            tRetrieveServers.Start();
        }
        private void buttonAdd_Click(object sender, EventArgs e)
        {
            for (int count = 0; count < listBoxServers.SelectedItems.Count;)
            {
                listBoxMonitor.Items.Add(listBoxServers.SelectedItems[count]);
                listBoxServers.Items.Remove(listBoxServers.SelectedItems[count]);
            }
        }

        private void buttonDelete_Click(object sender, EventArgs e)
        {
            for( int count = 0; count < listBoxMonitor.SelectedItems.Count;) 
            {
                listBoxServers.Items.Add(listBoxMonitor.SelectedItems[count]);
                listBoxMonitor.Items.Remove(listBoxMonitor.SelectedItems[count]);
            }
        }
        private void buttonStart_Click(object sender, EventArgs e)
        {
            try
            {
                Object[] oArray = new object[listBoxMonitor.Items.Count];
                System.TimeSpan tsRunningTime = dateTimePickerEndDate.Value.Subtract(System.DateTime.Now);
                int runningTime = tsRunningTime.Days * (60 / 5) * 24;
                progressBarStatus.Maximum = listBoxMonitor.Items.Count * runningTime;
                progressBarStatus.Minimum = 0;
                progressBarStatus.Step = 1;
                listBoxMonitor.Items.CopyTo(oArray, 0);
                buttonStart.Enabled = false;
                //chartMetrics.NValues = 5;
                //int count = 0;

                //foreach (Object o in oArray)
                //{
                //    if (count == chartMetrics.NValues)
                //        break;
                //    chartMetrics.Legend[count++] = (string)o;
                //    chartMetrics.Refresh(); 
                //}

                sm = new ServerMonitoring(oArray);
               
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
            }
        }
        private void buttonQuit_Click(object sender, EventArgs e)
        {
            if (sm != null)
            {
                sm.KillServerMonitoringThreads();
            }
            if (tUpdateProgressBar != null)
            {
                try
                {
                    switch (tUpdateProgressBar.ThreadState)
                    {
                        case System.Threading.ThreadState.Running:
                            tUpdateProgressBar.Abort();
                            break;
                        case System.Threading.ThreadState.Background:
                            tUpdateProgressBar.Abort();
                            break;
                        case System.Threading.ThreadState.Suspended:
                            tUpdateProgressBar.Abort();
                            break;
                        case System.Threading.ThreadState.WaitSleepJoin:
                            tUpdateProgressBar.Abort();
                            break;
                        default:
                            break;
                    }
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex.Message);
                }
            }
            Application.ExitThread();
        }
        private void ThreadUpdateProgressBar()
        {
            while (true)
            {
                try
                {
                    if (sm != null)
                    {
                        System.Threading.Monitor.Enter(sm);
                        try
                        {
                            Console.WriteLine("Performing Step...{0}", sm.progressCount - progressBarStatus.Value);
                            progressBarStatus.Step = sm.progressCount - progressBarStatus.Value;
                            progressBarStatus.PerformStep();
                            if (progressBarStatus.Maximum == progressBarStatus.Value)
                                this.buttonQuit_Click(null, null);
                        }
                        finally
                        {
                            System.Threading.Monitor.Exit(sm);
                        }
                    }
                    System.Threading.Thread.Sleep(5000);
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex.ToString());
                }
            }
        }

        private void buttonInitDB_Click(object sender, EventArgs e)
        {
            string deleteHardwareQuery      = "DELETE FROM HARDWARE";
            string deleteCandidatesQuery    = "DELETE FROM CANDIDATES";
            string deleteCPUQuery           = "DELETE FROM CPU";
            string deleteDiskQuery          = "DELETE FROM DISK";
            string deleteMemoryQuery        = "DELETE FROM MEMORY";
            string deleteNetworkQuery       = "DELETE FROM NETWORK";

            VMwareCandidateDataSetTableAdapters.HARDWARETableAdapter hardwareTA 
                = new VMwareCandidates.VMwareCandidateDataSetTableAdapters.HARDWARETableAdapter();
            VMwareCandidateDataSetTableAdapters.CANDIDATESTableAdapter candidatesTA
                    = new VMwareCandidates.VMwareCandidateDataSetTableAdapters.CANDIDATESTableAdapter();
            VMwareCandidateDataSetTableAdapters.CPUTableAdapter cpuTA
                = new VMwareCandidates.VMwareCandidateDataSetTableAdapters.CPUTableAdapter();
            VMwareCandidateDataSetTableAdapters.DISKTableAdapter diskTA
                = new VMwareCandidates.VMwareCandidateDataSetTableAdapters.DISKTableAdapter();
            VMwareCandidateDataSetTableAdapters.MEMORYTableAdapter memoryTA
                = new VMwareCandidates.VMwareCandidateDataSetTableAdapters.MEMORYTableAdapter();
            VMwareCandidateDataSetTableAdapters.NETWORKTableAdapter networkTA
                = new VMwareCandidates.VMwareCandidateDataSetTableAdapters.NETWORKTableAdapter();

            cpuTA.Connection.Open();
            System.Data.SqlClient.SqlCommand sqlcmdCpu
                = new System.Data.SqlClient.SqlCommand(deleteCPUQuery, cpuTA.Connection);
            sqlcmdCpu.ExecuteNonQuery();
            cpuTA.Connection.Close();

            diskTA.Connection.Open();
            System.Data.SqlClient.SqlCommand sqlcmdDisk
                = new System.Data.SqlClient.SqlCommand(deleteDiskQuery, diskTA.Connection);
            sqlcmdDisk.ExecuteNonQuery();
            diskTA.Connection.Close();

            memoryTA.Connection.Open();
            System.Data.SqlClient.SqlCommand sqlcmdMemory
                = new System.Data.SqlClient.SqlCommand(deleteMemoryQuery, memoryTA.Connection);
            sqlcmdMemory.ExecuteNonQuery();
            memoryTA.Connection.Close();

            networkTA.Connection.Open();
            System.Data.SqlClient.SqlCommand sqlcmdNetwork
                = new System.Data.SqlClient.SqlCommand(deleteNetworkQuery, networkTA.Connection);
            sqlcmdNetwork.ExecuteNonQuery();
            networkTA.Connection.Close();

            candidatesTA.Connection.Open();
            System.Data.SqlClient.SqlCommand sqlcmdCandidates
                = new System.Data.SqlClient.SqlCommand(deleteCandidatesQuery, candidatesTA.Connection);
            sqlcmdCandidates.ExecuteNonQuery();
            candidatesTA.Connection.Close();

            hardwareTA.Connection.Open();
            System.Data.SqlClient.SqlCommand sqlcmdHardware
                = new System.Data.SqlClient.SqlCommand(deleteHardwareQuery, hardwareTA.Connection);
            sqlcmdHardware.ExecuteNonQuery();
            hardwareTA.Connection.Close();
        }
    }
}